package com.platform.config.apidoc;

import com.platform.config.XlingProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StopWatch;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

import static com.platform.config.XlingConstants.SPRING_PROFILE_SWAGGER;
import static springfox.documentation.builders.PathSelectors.regex;

//import com.platform.modules.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;


/**
 * Swagger配置 Parameter Types OpenAPI 3.0 distinguishes between the following
 * parameter types based on the parameter location. The location is determined
 * by the parameter’s in key, for example, in: query or in: path.
 * <p>
 * path parameters, such as /users/{id} query parameters, such as
 * /users?role=admin header parameters, such as X-MyHeader: Value cookie
 * parameters, which are passed in the Cookie header, such as Cookie: debug=0;
 * csrftoken=BUSe35dohU3O1MZvDCU
 * <p>
 * Data Type allowMultiple=true, ————表示是数组格式的参数 "int", "double", "float",
 * "long", "biginteger", "bigdecimal", "byte", "boolean", "string", "object",
 * "__file"
 * <p>
 * 注意： int、double、float、long、biginteger、bigdecimal、byte、需要给example的值
 *
 * @author 肖亮
 */
@Profile(SPRING_PROFILE_SWAGGER)
@AutoConfigureAfter(XlingProperties.class)
@Configuration
@EnableSwagger2
public class SwaggerConfig {

	static final String STARTING_MESSAGE = "Starting Swagger";
	static final String STARTED_MESSAGE = "Started Swagger in {} ms";

	private final Logger log = LoggerFactory.getLogger(SwaggerConfig.class);



	private final XlingProperties.Swagger properties;

	public SwaggerConfig(XlingProperties properties) {
		this.properties = properties.getSwagger();
	}

	@Bean
	public Docket swaggerSpringfoxApiDocket() {

		log.debug(STARTING_MESSAGE);
		StopWatch watch = new StopWatch();
		watch.start();

		Docket docket = createDocket();
		customize(docket);

//		Docket docket = createDocket()
//				.apiInfo(apiInfo())
//				.useDefaultResponseMessages(false)
//				.select()
//				.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))   //RequestHandlerSelectors.any()
//			 	.paths(PathSelectors.regex("^(?!auth).*$"))
//			 	.build()
				//.securitySchemes(security())
				//.securityContexts(securityContexts())
//			 ;

		watch.stop();
		log.debug(STARTED_MESSAGE, watch.getTotalTimeMillis());

		return docket;
//		return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
//				// 加了ApiOperation注解的类，才生成接口文档
//				.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any())
//				.build().securitySchemes(security()).securityContexts(securityContexts());
	}

	
	@Deprecated
	private ApiInfo apiInfo() {
		return new ApiInfoBuilder()
				.title(" 建筑工程质量监管系统")
				//.description(" 建筑工程质量监管系统台API接口文档")
				.version("1.0.0")
				//.contact(new Contact("肖亮", "http://www.xiaolingjituang.com", "635620856@qq.com"))
				.build();
	}
	@Deprecated
	private List<ApiKey> security() {
		return Arrays.asList(new ApiKey("token", "token", "header"));
		
	}
	@Deprecated
  	private List<SecurityContext> securityContexts() {
		return Arrays.asList(
				SecurityContext.builder()
						.securityReferences(defaultAuth())
						.forPaths(PathSelectors.regex("^(?!auth).*$"))
						.build()
		);
	}
	@Deprecated
	private List<SecurityReference> defaultAuth() {
		AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
		AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
		authorizationScopes[0] = authorizationScope;
		return Arrays.asList(
				new SecurityReference("token", authorizationScopes));
	}

	protected Docket createDocket() {
		return new Docket(DocumentationType.SWAGGER_2);
	}

	public void customize(Docket docket) {
		Contact contact = new Contact(
				properties.getContactName(),
				properties.getContactUrl(),
				properties.getContactEmail()
		);

		ApiInfo apiInfo = new ApiInfo(
				properties.getTitle(),
				properties.getDescription(),
				properties.getVersion(),
				properties.getTermsOfServiceUrl(),
				contact,
				properties.getLicense(),
				properties.getLicenseUrl(),
				new ArrayList<>()
		);

		docket.host(properties.getHost())
				.protocols(new HashSet<>(Arrays.asList(properties.getProtocols())))
				.apiInfo(apiInfo)
				.useDefaultResponseMessages(properties.isUseDefaultResponseMessages())
				.forCodeGeneration(true)
				.directModelSubstitute(ByteBuffer.class, String.class)
				.genericModelSubstitutes(ResponseEntity.class)
				//.ignoredParameterTypes(Pageable.class)
				.select()
				//.paths(regex(properties.getDefaultIncludePattern()))
				.build();
	}
}